Scramble string¶
Time: O(N^4); Space: O(N^3); hard
Given a string s1, we may represent it as a binary tree by partitioning it to two non-empty substrings recursively.
Below is one possible representation of s1 = “great”:
great
/ \
gr eat
/ \ / \
g r e at
/ \
a t
To scramble the string, we may choose any non-leaf node and swap its two children.
For example, if we choose the node “gr” and swap its two children, it produces a scrambled string “rgeat”.
rgeat
/ \
rg eat
/ \ / \
r g e at
/ \
a t
We say that “rgeat” is a scrambled string of “great”.
Similarly, if we continue to swap the children of nodes “eat” and “at”, it produces a scrambled string “rgtae”.
rgtae
/ \
rg tae
/ \ / \
r g ta e
/ \
t a
We say that “rgtae” is a scrambled string of “great”.
Given two strings s1 and s2 of the same length, determine if s2 is a scrambled string of s1.
Example 1:
Input: s1 = “great”, s2 = “rgeat”
Output: True
Explanation:
As described above.
Example 2:
Input: s1 = “abcde”, s2 = “caebd”
Output: False
[1]:
class Solution1(object):
"""
Time: O(N^4)
Space: O(N^3)
"""
def isScramble(self, s1, s2):
"""
:type s1: str
:type s2: str
:rtype: bool
"""
if not s1 or not s2 or len(s1) != len(s2):
return False
if s1 == s2:
return True
result = [[[False for j in range(len(s2))] for i in range(len(s1))] for n in range(len(s1) + 1)]
for i in range(len(s1)):
for j in range(len(s2)):
if s1[i] == s2[j]:
result[1][i][j] = True
for n in range(2, len(s1) + 1):
for i in range(len(s1) - n + 1):
for j in range(len(s2) - n + 1):
for k in range(1, n):
if result[k][i][j] and result[n - k][i + k][j + k] or\
result[k][i][j + n - k] and result[n - k][i + k][j]:
result[n][i][j] = True
break
return result[n][0][0]
[2]:
s = Solution1()
s1 = "great"
s2 = "rgeat"
assert s.isScramble(s1, s2) == True
s1 = "abcde"
s2 = "caebd"
assert s.isScramble(s1, s2) == False